home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
MOR55SRC.ZIP
/
MORIA
/
IBMPC
/
MS_MISC.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-12-08
|
11KB
|
512 lines
/* ibmpc/ms_misc.c: MSDOS support code
Copyright (c) 1989-92 James E. Wilson, Don Kneller
This software may be copied and distributed for educational, research, and
not for profit purposes provided that this copyright and statement are
included in all such copies. */
#ifdef __TURBOC__
#include <conio.h>
#endif /* __TURBOC__ */
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <fcntl.h>
#include <stdio.h>
#include "config.h"
#include "constant.h"
#include "types.h"
#include "externs.h"
#ifdef MSDOS
#ifndef USING_TCIO
/* We don't want to include curses.h when using the tcio.c file. */
#include <curses.h>
#endif
#ifdef ANSI
#include "ms_ansi.h"
#endif
#ifdef LINT_ARGS
void exit(int);
static FILE *fopenp(char *, char *, char *);
static unsigned int ioctl(int ,int ,unsigned int );
#else
void exit();
static unsigned int ioctl();
#endif
extern char *getenv();
#define PATHLEN 80
char moriatop[PATHLEN];
char moriasav[PATHLEN];
int saveprompt = TRUE;
int ibmbios;
static int rawio;
int8u floorsym = '.';
int8u wallsym = '#';
/* UNIX compatability routines */
void user_name(buf)
char *buf;
{
strcpy(buf, getlogin());
}
char *
getlogin()
{
char *cp;
if ((cp = getenv("USER")) == NULL)
cp = "player";
return cp;
}
#ifndef __TURBOC__
unsigned int
sleep(secs)
int secs;
{
time_t finish_time;
finish_time = time((long *) NULL) + secs;
while (time((long *) NULL) < finish_time)
/* nothing */;
return 0;
}
#endif
#ifdef OLD
/* This is the old code. It is not strictly correct; it is retained in
case the correct code below is not portable. You will also have to
change the declarations for these functions in externs.h. */
void
error(fmt, a1, a2, a3, a4)
char *fmt;
int a1, a2, a3, a4;
{
fprintf(stderr, "MORIA error: ");
fprintf(stderr, fmt, a1, a2, a3, a4);
(void) sleep(2);
exit(1);
}
void
warn(fmt, a1, a2, a3, a4)
char *fmt;
int a1, a2, a3, a4;
{
fprintf(stderr, "MORIA warning: ");
fprintf(stderr, fmt, a1, a2, a3, a4);
(void) sleep(2);
}
#else
#include <stdarg.h>
void
error (char *fmt, ...)
{
va_list p_arg;
va_start (p_arg, fmt);
fprintf (stderr, "Moria error: ");
vfprintf (stderr, fmt, p_arg);
sleep (2);
exit (1);
}
void
warn(char *fmt, ...)
{
va_list p_arg;
va_start(p_arg, fmt);
fprintf(stderr, "MORIA warning: ");
vfprintf(stderr, fmt, p_arg);
sleep(2);
}
#endif
/* Search the path for a file of name "name". The directory is
* filled in with the directory part of the path.
*/
static FILE *
fopenp(name, mode, directory)
char *name, *mode, directory[];
{
char *dp, *pathp, *getenv(), lastch;
FILE *fp;
/* Try the default directory first. If the file can't be opened,
* start looking along the path.
*/
fp = fopen (name, mode);
if (fp) {
directory[0] = '\0';
return fp;
}
pathp = getenv("PATH");
while (pathp && *pathp) {
dp = directory;
while (*pathp && *pathp != ';')
lastch = *dp++ = *pathp++;
if (lastch != '\\' && lastch != '/' && lastch != ':')
*dp++ = '\\';
(void) strcpy(dp, name);
fp = fopen (directory, mode);
if (fp) {
*dp = '\0';
return fp;
}
if (*pathp)
pathp++;
}
directory[0] = '\0';
return NULL;
}
/* Read the configuration.
*/
void
msdos_init()
{
char buf[BUFSIZ], *bp, opt[PATHLEN];
int arg1, arg2, cnt;
FILE *fp;
buf[0] = '\0';
bp = MORIA_CNF_NAME;
fp = fopenp(bp, "r", buf);
(void) strcpy(moriatop, buf);
(void) strcat(moriatop, MORIA_TOP_NAME);
(void) strcpy(moriasav, buf);
(void) strcat(moriasav, MORIA_SAV_NAME);
if (fp == NULL) {
warn("Can't find configuration file `%s'\n", bp);
return;
}
printf("Reading configuration from %s%s\n", buf, bp);
(void) sleep(1);
while (fgets(buf, sizeof buf, fp)) {
if (*buf == '#')
continue;
cnt = sscanf(buf, "%s", opt);
/* Turbo C will return EOF when reading an empty line,
MSC will correctly read a NULL character */
if (cnt == 0 ||
#ifdef __TURBOC__
cnt == EOF ||
#endif
opt[0] == '\0')
continue;
/* Go through possible variables
*/
if (strcmpi(opt, "GRAPHICS") == 0) {
cnt = sscanf(buf, "%*s%d %d\n", &arg1, &arg2);
if (cnt != 2)
warn("GRAPHICS did not contain 2 values\n");
else {
wallsym = (int8u) arg1;
floorsym = (int8u) arg2;
/* Adjust lists that depend on '#' and '.' */
object_list[OBJ_SECRET_DOOR].tchar = wallsym;
}
}
else if (strcmpi(opt, "SAVE") == 0) {
cnt = sscanf(buf, "%*s%s", opt);
if (cnt == 0)
warn("SAVE option requires a filename\n");
else {
bp = strchr (opt, ';');
if (bp) {
*bp++ = '\0';
if (*bp == 'n' || *bp == 'N')
saveprompt = FALSE;
}
if (opt[0])
(void) strcpy(moriasav, opt);
}
}
else if (strcmpi(opt, "SCORE") == 0) {
cnt = sscanf(buf, "%*s%s", opt);
if (cnt == 0)
warn("SCORE option requires a filename\n");
else
(void) strcpy(moriatop, opt);
}
else if (strcmpi(opt, "KEYBOARD") == 0) {
cnt = sscanf(buf, "%*s%s", opt);
if (cnt == 0)
warn("KEYBOARD option requires a value\n");
else if (strcmpi(opt, "ROGUE") == 0)
rogue_like_commands = TRUE;
else if (strcmpi(opt, "VMS") == 0)
rogue_like_commands = FALSE;
}
else if (strcmpi(opt, "IBMBIOS") == 0)
ibmbios = TRUE;
else if (strcmpi(opt, "RAWIO") == 0)
rawio = TRUE;
#ifdef ANSI
/* Usage: ANSI [ check_ansi [ domoveopt [ tgoto ] ] ]
* where check_ansi and domoveopt are "Y"es unless explicitly
* set to "N"o. Tgoto is "N"o unless set to "Y"es.
*/
else if (strcmpi(opt, "ANSI") == 0) {
cnt=sscanf(buf, "%*s%1s%1s%1s",&opt[0],&opt[1],&opt[2]);
ansi_prep(cnt < 1 || opt[0] == 'y' || opt[0] == 'Y',
cnt < 2 || opt[1] == 'y' || opt[1] == 'Y',
cnt >= 3 && (opt[2] == 'y' || opt[2] == 'Y'));
}
#endif
else
warn("Unknown configuration line: `%s'\n", buf);
}
fclose(fp);
/* The only text file has been read. Switch to binary mode */
}
#include <dos.h>
#define DEVICE 0x80
#define RAW 0x20
#define IOCTL 0x44
#define STDIN fileno(stdin)
#define STDOUT fileno(stdout)
#define GETBITS 0
#define SETBITS 1
static unsigned old_stdin, old_stdout, ioctl();
void
msdos_raw() {
if (!rawio)
return;
old_stdin = ioctl(STDIN, GETBITS, 0);
old_stdout = ioctl(STDOUT, GETBITS, 0);
if (old_stdin & DEVICE)
ioctl(STDIN, SETBITS, old_stdin | RAW);
if (old_stdout & DEVICE)
ioctl(STDOUT, SETBITS, old_stdout | RAW);
}
void
msdos_noraw() {
if (!rawio)
return;
if (old_stdin)
(void) ioctl(STDIN, SETBITS, old_stdin);
if (old_stdout)
(void) ioctl(STDOUT, SETBITS, old_stdout);
}
static unsigned int
ioctl(handle, mode, setvalue)
unsigned int setvalue;
{
union REGS regs;
regs.h.ah = IOCTL;
regs.h.al = (unsigned char) mode;
regs.x.bx = handle;
regs.h.dl = (unsigned char) setvalue;
regs.h.dh = 0; /* Zero out dh */
intdos(®s, ®s);
return (regs.x.dx);
}
/* Normal characters are output when the shift key is not pushed.
* Shift characters are output when either shift key is pushed.
*/
#define KEYPADHI 83
#define KEYPADLOW 71
#define ISKEYPAD(x) (KEYPADLOW <= (x) && (x) <= KEYPADHI)
#undef CTRL
#define CTRL(x) (x - '@')
typedef struct {
char normal, shift, numlock;
} KEY;
static KEY roguekeypad[KEYPADHI - KEYPADLOW + 1] = {
{'y', 'Y', CTRL('Y')}, /* 7 */
{'k', 'K', CTRL('K')}, /* 8 */
{'u', 'U', CTRL('U')}, /* 9 */
{'.', '.', '.'}, /* - */
{'h', 'H', CTRL('H')}, /* 4 */
{'.', '.', '.'}, /* 5 */
{'l', 'L', CTRL('L')}, /* 6 */
{CTRL('P'), CTRL('P'), CTRL('P')}, /* + */
{'b', 'B', CTRL('B')}, /* 1 */
{'j', 'J', CTRL('J')}, /* 2 */
{'n', 'N', CTRL('N')}, /* 3 */
{'i', 'i', 'i'}, /* Ins */
{'.', '.', '.'} /* Del */
};
static KEY originalkeypad[KEYPADHI - KEYPADLOW + 1] = {
{'7', '7', '7'}, /* 7 */
{'8', '8', '8'}, /* 8 */
{'9', '9', '9'}, /* 9 */
{'-', '-', '-'}, /* - */
{'4', '4', '4'}, /* 4 */
{'5', '5', '5'}, /* 5 - move */
{'6', '6', '6'}, /* 6 */
{CTRL('M'), CTRL('M'), CTRL('M')}, /* + */
{'1', '1', '1'}, /* 1 */
{'2', '2', '2'}, /* 2 */
{'3', '3', '3'}, /* 3 */
{'i', 'i', 'i'}, /* Ins */
{'.', '.', '.'} /* Del */
};
/* bios_getch gets keys directly with a BIOS call.
*/
#define SHIFT (0x1 | 0x2)
#define NUMLOCK 0x20
#define KEYBRD_BIOS 0x16
int
bios_getch()
{
unsigned char scan, shift;
int ch;
KEY *kp;
union REGS regs;
if (rogue_like_commands)
kp = roguekeypad;
else
kp = originalkeypad;
/* Get scan code.
*/
regs.h.ah = 0;
int86(KEYBRD_BIOS, ®s, ®s);
ch = regs.h.al;
scan = regs.h.ah;
/* Get shift status.
*/
regs.h.ah = 2;
int86(KEYBRD_BIOS, ®s, ®s);
shift = regs.h.al;
/* If scan code is for the keypad, translate it.
*/
if (ISKEYPAD(scan)) {
if (shift & NUMLOCK)
ch = kp[scan - KEYPADLOW].numlock;
else if (shift & SHIFT)
ch = kp[scan - KEYPADLOW].shift;
else
ch = kp[scan - KEYPADLOW].normal;
}
return ch;
}
int
msdos_getch()
{
int ch;
if (ibmbios)
ch = bios_getch();
else {
ch = getch();
if (ch == 0)
ch = getch();
}
return ch;
}
#if 0
/* This intro message deleted because it is obsolete. */
/* Hardcode the introductory message in */
void
msdos_intro()
{
char buf[80];
clear_screen();
wmove(stdscr,0,0);
waddstr(stdscr," *********************");
wmove(stdscr,1,0);
sprintf(buf," ** Moria %d.%d **",
CUR_VERSION_MAJ, CUR_VERSION_MIN);
waddstr(stdscr,buf);
wmove(stdscr,2,0);
waddstr(stdscr," *********************");
wmove(stdscr,3,0);
waddstr(stdscr," COPYRIGHT (c) Robert Alan Koeneke");
wmove(stdscr,5,0);
waddstr(stdscr,"Programmers : Robert Alan Koeneke / University of Oklahoma");
wmove(stdscr,6,0);
waddstr(stdscr," Jimmey Wayne Todd / University of Oklahoma");
wmove(stdscr,8,0);
waddstr(stdscr,"UNIX Port : James E. Wilson / Cygnus Support");
wmove(stdscr,10,0);
waddstr(stdscr,"MSDOS Port : Don Kneller / 1349 - 10th ave");
wmove(stdscr,11,0);
waddstr(stdscr,
" / San Francisco, CA 94122");
wmove(stdscr,12,0);
waddstr(stdscr," / Dec 12, 1988");
pause_line(23);
}
#endif
#ifdef PC_CURSES
/* Seems to be a bug in PCcurses whereby it won't really clear the screen
* if there are characters there it doesn't know about.
*/
#define VIDEOINT 0x10
void
bios_clear()
{
union REGS regs;
unsigned char nocols, activepage;
#ifdef ANSI
if (ansi)
return;
#endif
/* get video attributes */
regs.h.ah = 15;
int86(VIDEOINT, ®s, ®s);
nocols = regs.h.ah;
activepage = regs.h.bh;
/* Move to lower right corner */
regs.h.ah = 2;
regs.h.dh = (unsigned char) 24;
regs.h.dl = nocols - 1; /* lower right col */
regs.h.bh = activepage;
int86(VIDEOINT, ®s, ®s);
/* get current attribute into bh */
regs.h.ah = 8;
regs.h.bh = activepage;
int86(VIDEOINT, ®s, ®s);
regs.h.bh = regs.h.ah;
regs.h.cl = 0; /* upper left row */
regs.h.ch = 0; /* upper left col */
regs.h.dh = (unsigned char) 24; /* lower right row */
regs.h.dl = nocols - 1; /* lower right col */
regs.h.al = 0; /* clear window */
regs.h.ah = 7; /* scroll down */
int86(VIDEOINT, ®s, ®s);
}
#endif
#endif